package com.cndw.kungfu.ext;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import com.cndw.commons.util.StringUtils;

/**
 * 身份证检查
 * 
 * 
 * 
 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
 * 
 * @since 1.0 Create on 2011-11-23
 */
public class IDCardCheck {

	private static final int[] Wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };// 加权因子
	private static final int[] ValideCode = { 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };// 身份证验证位值.10代表X

	public static boolean IdCardValidate(String idCard) {

		if (idCard.length() == 15 && StringUtils.isPositiveInteger(idCard)) {
			return isValidityBrithBy15IdCard(idCard);
		}

		if (idCard.length() == 18 && StringUtils.isPositiveInteger(idCard.substring(1, 17))) {
			if (isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(idCard)) {
				return true;
			} else {
				return false;
			}
		}
		return false;
	}

	/**
	 * 判断身份证号码为18位时最后的验证位是否正确
	 * 
	 * @param a_idCard
	 *            身份证号码数组
	 * @return
	 */
	public static boolean isTrueValidateCodeBy18IdCard(String idCard) {

		long sum = 0; // 声明加权求和变量
		char[] a_idCard = idCard.toCharArray();

		if (Character.toLowerCase(a_idCard[17]) == 'x') {
			a_idCard[17] = Character.forDigit(10, 16);// 将最后位为x的验证码替换为10方便后续操作
		}

		for (int i = 0; i < 17; i++) {
			sum += Wi[i] * Character.digit(a_idCard[i], 10);// 加权求和
		}

		int position = (int) (sum % 11);// 得到验证码所位置

		return Character.digit(a_idCard[17], 16) == ValideCode[position];
	}

	/**
	 * 通过身份证判断是男是女
	 * 
	 * @param idCard
	 *            15/18位身份证号码
	 * @return 'female'-女、'male'-男
	 */
	public static String maleOrFemalByIdCard(String idCard) {
		idCard = idCard.trim();

		if (idCard.length() == 15) {
			if (Integer.parseInt(idCard.substring(14, 15)) % 2 == 0) {
				return "female";
			} else {
				return "male";
			}
		}

		if (idCard.length() == 18) {
			if (Integer.parseInt(idCard.substring(14, 17)) % 2 == 0) {
				return "female";
			} else {
				return "male";
			}
		}

		return null;
	}

	/**
	 * 验证18位数身份证号码中的生日是否是有效生日
	 * 
	 * @param idCard
	 *            18位书身份证字符串
	 * @return
	 */
	public static boolean isValidityBrithBy18IdCard(String idCard18) {
		return isValidate(idCard18.substring(6, 14), "yyyyMMdd");
	}

	/**
	 * 验证15位数身份证号码中的生日是否是有效生日
	 * 
	 * @param idCard15
	 *            15位书身份证字符串
	 * @return
	 */
	public static boolean isValidityBrithBy15IdCard(String idCard15) {
		return isValidate(idCard15.substring(6, 12), "yyMMdd");
	}

	private static boolean isValidate(String brith, String pattern) {
		try {
			DateFormat format = new SimpleDateFormat(pattern);
			format.setLenient(false);
			format.parse(brith);
			return true;
		} catch (ParseException e) {
			return false;
		}
	}

	public static void main(String[] args) {
		System.out.println(IdCardValidate("43042219880701921X"));
	}

}
